package com.ruoyi.huanjing.service;
import com.ruoyi.huanjing.entity.Atmospheric;
import ucar.ma2.Array;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class ReadFileToHot {
    // 全局变量，用于存储经纬度数据
    private static Array globalLonData = null;
    private static Array globalLatData = null;
    
    public static void main(String[] args) throws IOException {
        String filePath = "E:\\localfile\\MYD021KM.A2017314.0345.061.2017314164621.hdf";
        List<Atmospheric> list = readDataFromHDF(filePath);
        // 打印数据
        for (Atmospheric atmospheric : list) {
            System.out.println(atmospheric);
        }
    }

    private static List<Atmospheric> readDataFromHDF(String filePath) throws IOException { 
        try (NetcdfFile ncFile = NetcdfFile.open(filePath)) { 
            // 查找 Height 变量 
            Variable heightVar = ncFile.findVariable("MODIS_SWATH_Type_L1B/Data_Fields/Height"); 
            if (heightVar == null) { 
                throw new RuntimeException("未找到 Height 变量"); 
            } 
            Array heightData = heightVar.read(); 
            int[] shape = heightVar.getShape(); 
            int ySize = shape[0]; 
            int xSize = shape[1]; 

            // 定义可能的经纬度变量名 
            String[] latNames = {"lat", "latitude", "Latitude"}; 
            String[] lonNames = {"lon", "longitude", "Longitude"}; 

            // 递归查找纬度变量 
            Variable latVar = findVariableRecursively(ncFile, latNames); 
            if (latVar == null) { 
                throw new RuntimeException("未找到纬度变量，尝试查找的变量名：" + String.join(", ", latNames)); 
            } 

            // 递归查找经度变量 
            Variable lonVar = findVariableRecursively(ncFile, lonNames); 
            if (lonVar == null) { 
                throw new RuntimeException("未找到经度变量，尝试查找的变量名：" + String.join(", ", lonNames)); 
            } 

            // 存储经纬度数据到全局变量 
            globalLonData = lonVar.read(); 
            globalLatData = latVar.read(); 

            List<Atmospheric> atmosphericList = new ArrayList<>(); 
            for (int y = 0; y < ySize; y++) { 
                for (int x = 0; x < xSize; x++) { 
                    // 从全局变量中读取经纬度值 
                    double lon = globalLonData.getDouble(globalLonData.getIndex().set(y, x)); 
                    double lat = globalLatData.getDouble(globalLatData.getIndex().set(y, x)); 
                    short value = heightData.getShort(heightData.getIndex().set(y, x)); 

                    // 处理无效值，根据 valid_range 和 _FillValue 过滤 
                    if (value != -32767 && value >= -400 && value <= 10000) { 
                        Atmospheric atmospheric = new Atmospheric(); 
                        atmospheric.setLon(BigDecimal.valueOf(lon)); 
                        atmospheric.setLat(BigDecimal.valueOf(lat)); 
                        atmospheric.setValue(BigDecimal.valueOf(value)); 
                        atmosphericList.add(atmospheric); 
                    } 
                } 
            } 
            return atmosphericList; 
        } 
    } 

    // 递归查找变量的方法 
    private static Variable findVariableRecursively(NetcdfFile ncFile, String[] names) { 
        List<Variable> allVariables = new ArrayList<>(); 
        collectAllVariables(ncFile.getRootGroup(), allVariables); 

        for (Variable var : allVariables) { 
            for (String name : names) { 
                if (var.getShortName().equalsIgnoreCase(name)) { 
                    return var; 
                } 
            } 
        } 
        return null; 
    } 

    // 递归收集所有变量的方法 
    private static void collectAllVariables(ucar.nc2.Group group, List<Variable> variables) { 
        variables.addAll(group.getVariables()); 
        for (ucar.nc2.Group subgroup : group.getGroups()) { 
            collectAllVariables(subgroup, variables); 
        } 
    } 

    // 添加获取经纬度数据的方法，方便后续绘图使用 
    public static Array getGlobalLonData() { 
        return globalLonData; 
    } 

    public static Array getGlobalLatData() { 
        return globalLatData; 
    } 
}